package com.yuantu.judiciary.serviceimpl;

import com.alibaba.fastjson2.JSON;
import com.yuantu.judiciary.dao.IQueryEntityDao;
import com.yuantu.judiciary.dao.IQueryRecordDao;
import com.yuantu.judiciary.dao.IUserRelationDao;
import com.yuantu.judiciary.exception.enums.CheckPersonExceptionEnum;
import com.yuantu.judiciary.model.domain.QueryEntityDO;
import com.yuantu.judiciary.model.domain.QueryRecordDO;
import com.yuantu.judiciary.model.domain.UserRelationDO;
import com.yuantu.judiciary.model.dto.SearchRecordContentDTO;
import com.yuantu.judiciary.model.enums.UserRelationType;
import com.yuantu.judiciary.model.form.GetQueryInfoForm;
import com.yuantu.judiciary.model.form.SearchRelationForm;
import com.yuantu.judiciary.model.vo.PageVO;
import com.yuantu.judiciary.model.vo.UserRelationVO;
import com.yuantu.judiciary.service.ICheckResultService;
import com.yuantu.judiciary.service.IUserRelationService;
import com.yuantu.judiciary.utils.AssertUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 用户关系
 *
 * @author syw
 * @since 2023-07-25
 **/
@Service
@RequiredArgsConstructor
public class UserRelationServiceImpl implements IUserRelationService {

    private final IQueryRecordDao queryRecordDao;
    private final IQueryEntityDao queryEntityDao;
    private final IUserRelationDao userRelationDao;
    private final ICheckResultService checkResultService;

    @Override
    public Boolean add(Long userId, GetQueryInfoForm form, UserRelationType type) {
        QueryRecordDO queryRecord = queryRecordDao.findByIdAndDeletedFalse(form.getId());
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(queryRecord), CheckPersonExceptionEnum.QUERY_RECORD_NOT_EXIST);

        QueryEntityDO entity = checkResultService.getQueryEntity(userId, queryRecord, JSON.parseObject(queryRecord.getContent(), SearchRecordContentDTO.class));
        UserRelationDO relation = userRelationDao.findByEntityIdAndCreatorIdAndTypeAndDeletedFalse(entity.getId(), userId, type);
        if (ObjectUtils.isEmpty(relation)) {
            UserRelationDO userRelation = new UserRelationDO();
            userRelation.setEntityId(entity.getId());
            userRelation.setType(type);
            userRelation.setCreatorId(userId);
            userRelationDao.save(userRelation);
        }

        return true;
    }

    @Override
    public Boolean cancel(Long userId, GetQueryInfoForm form, UserRelationType type) {
        QueryRecordDO queryRecord = queryRecordDao.findByIdAndDeletedFalse(form.getId());
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(queryRecord), CheckPersonExceptionEnum.QUERY_RECORD_NOT_EXIST);

        UserRelationDO relation = userRelationDao.findByEntityIdAndCreatorIdAndTypeAndDeletedFalse(queryRecord.getEntityId(), userId, type);
        if (!ObjectUtils.isEmpty(relation)) {
            relation.setDeleted(true);
            userRelationDao.save(relation);
        }

        return true;
    }

    @Override
    public PageVO<UserRelationVO> getRelationPage(Long userId, Pageable pageable, UserRelationType type, SearchRelationForm form) {
        Page<UserRelationDO> page = userRelationDao.getRelationByCreatorIdAndTypeAndNameLike(userId, type, form.getName(), pageable);
        if (CollectionUtils.isEmpty(page.getContent())) {
            return new PageVO<>(page.getTotalElements(), Collections.emptyList());
        }
        List<Long> entityIds = page.getContent().stream()
                .filter(Objects::nonNull)
                .map(UserRelationDO::getEntityId).distinct()
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(entityIds)) {
            return new PageVO<>(page.getTotalElements(), Collections.emptyList());
        }
        Map<Long, String> entityMap = queryEntityDao.findByIdInAndDeletedFalse(entityIds).stream()
                .collect(Collectors.toMap(QueryEntityDO::getId, QueryEntityDO::getName));
        Map<Long, Long> queryMap = queryRecordDao.findByCreatorIdAndEntityIdInAndDeletedFalse(userId, entityIds).stream()
                .collect(Collectors.toMap(QueryRecordDO::getEntityId, QueryRecordDO::getId));
        return new PageVO<>(page.getTotalElements(), page.getContent().stream().map(data ->
                new UserRelationVO(queryMap.get(data.getEntityId()), entityMap.get(data.getEntityId()))
        ).collect(Collectors.toList()));
    }

}
